from sqlalchemy import Column, Integer, String, Date, Text, Time, Boolean, func

from core.base.base_model import BaseModel
from core.utils.time_utils import DateTimeUtils
from core.utils.list_utils import list_find


class Task(BaseModel):
    __tablename__ = 'task'  # 表名

    employee_id = Column(Integer)
    name = Column(String(50))
    date = Column(Date)
    status = Column(Integer)  # 0 未完成 1 已完成 2 进行中
    tomato_len = Column(Integer, doc="番茄时长")
    tomato_count = Column(Integer, doc="番茄个数")
    recycle_type = Column(Integer, doc="循环类型")  # 0不循环，1每日循环，2每周循环，3每月循环，4每年循环
    # 1每日循环 1:表示每天循环 2:表示每两天一次，依次类推 2. 每周循环:是一个元祖1-7表示每周的周几 3. 每月循环，先醉倒每周就行了
    cycle_content = Column(String(50))
    start_date = Column(Date, doc="任务开始日期")
    end_date = Column(Date, doc="任务的结束日期")  # 任务的结束日期
    note = Column(Text, doc="备注")
    is_plan = Column(Boolean, doc="已计划")
    continue_days = Column(Integer, doc="连续天数")
    start_time = Column(Time, doc="计划开始时间")
    end_time = Column(Time, doc="计划结束时间")
    total_days = Column(Integer, doc="总共天数")
    total_minutes = Column(Integer, doc="总共分钟数")
    group_id = Column(Integer, doc="分组id", info=dict(object="TaskGroup"))
    background = Column(String(100))  # 用于保存背景图片或者颜色值

    @classmethod
    def get_employee_task(cls, employee_id, status, date=None, is_plan=None, is_group=False):
        query = cls.db().query(cls.id).filter(cls.employee_id == employee_id)
        if status is not None:
            query = query.filter(cls.status == status)
        if date:
            if date == "nodate":
                query = query.filter(cls.date == None)
            else:
                query = query.filter(
                    cls.end_date >= date,
                    cls.date <= date
                )
        if is_plan:
            query = query.filter(cls.is_plan == is_plan)

        tasks = query.all()

        tasks = cls.super_mget_json([_i.id for _i in tasks], id_map=False)

        _result, no_group_tasks = [], []
        if is_group:
            for _t in tasks:

                if any([
                    not _t.get("group_id") and not _t.get("group"),
                    _t.get("group_id") and not _t.get("group")
                ]):
                    no_group_tasks.append(_t)
                    continue
                group = list_find(_result, lambda _r: _t.get(
                    "group_id") and _r["id"] == _t["group_id"])
                if group:
                    # 如果group没有sequence那么给个100000
                    if not group.get("sequence"):
                        group["sequence"] = 100000
                    group["children"].append(_t)
                else:
                    _result.append({
                        **_t.get("group", {}),
                        "children": [_t]
                    })
            if no_group_tasks:
                _result.append({
                    "id": -1,
                    "name": "未分组",
                    "sequence": 1,  # 未分组默认第一个
                    "children": no_group_tasks
                })
            # 按照sequence进行排序
            _result = list(
                sorted(_result, key=lambda _i: _i.get("sequence") or 10000))
        else:
            _result = tasks

        return _result

    @classmethod
    def complete_task(cls, task_id):
        """完成任务

        :param task_id: _description_
        """
        task_info = cls.super_get_json(task_id)
        edit_dict = dict()
        recycle_type = task_info.get("recycle_type", 0)
        cycle_content = task_info.get("cycle_content", 0)
        if recycle_type == 0:
            edit_dict["status"] = 1
        elif recycle_type == 1:
            days = int(cycle_content)
            edit_dict["date"] = DateTimeUtils.add_days(edit_dict["date"], days)
            # TODO:超期任务处理
        elif recycle_type == 2:
            date_week = DateTimeUtils.get_week_day(edit_dict["date"])
            week_list = cycle_content.split(",") + [date_week]
            week_list.sort()
            # 获取到下一个任务是周几
            _index = week_list.index(date_week)
            next_week_number = _index
            for _i in week_list[_index:]:
                if _i == week_list[_index]:
                    continue
                next_week_number = _i
                break
            edit_dict["date"] = DateTimeUtils.get_date_by_week_number(
                next_week_number
            )
        else:
            edit_dict["status"] = 1
        # 编辑任务表格
        cls.update_data(task_id, edit_dict)
        # 添加完成记录
        TaskComplete.create_data(dict(
            employee_id=task_info.get("employee_id"), task_id=task_id,
            complete_time=DateTimeUtils.get_current_datetime_str()
        ))


class TaskPlan(BaseModel):
    __tablename__ = 'task_plan'  # 表名
    __description__ = "任务计划"

    employee_id = Column(Integer)
    task_id = Column(Integer, info=dict(object="Task"))
    start_time = Column(String(20), doc="开始时间")
    end_time = Column(String(20), doc="结束时间")
    end_date = Column(Date, doc="计划结束日期")

    @classmethod
    def get_employee_plan_task(cls, employee_id, date=""):
        query = cls.db().query(
            cls.id
        ).filter(
            cls.employee_id == employee_id,
        )
        if date:
            query.filter(cls.end_date >= date)
        ids = query.all()

        return cls.super_mget_json([_i.id for _i in ids])


class TaskComplete(BaseModel):
    __tablename__ = 'task_complete'  # 表名
    __description__ = "任务完成记录"

    employee_id = Column(Integer)
    task_id = Column(Integer)
    complete_time = Column(Time, doc="完成时间")


class TaskGroup(BaseModel):
    __tablename__ = 'tomato_group'  # 表名

    employee_id = Column(Integer)
    name = Column(String(50))
    status = Column(Integer, doc="状态", default=0)  # 0 废弃 1 使用中
    sequence = Column(Integer, doc="排序码", default=10000)  # 用于任务之间的排序

    @classmethod
    def add_task_group(cls, employee_id, task_name, sequence=1):
        """添加任务分组

        :param employee_id: _description_
        :param task_name: _description_
        :param suquence: 不传递的话排在最前面
        :return: _description_
        """
        # 进行校验
        if not task_name:
            return {"status": False}
        group = cls.db().query(cls.id).filter(
            cls.employee_id == employee_id,
            cls.name == task_name
        ).all()
        if group:
            return {"status": False}
        data = cls.create_data(dict(
            employee_id=employee_id,
            name=task_name,
            sequence=sequence
        ))

        return data

    @classmethod
    def get_groups_by_employee_id(cls, employee_id):
        groups = cls.db().query(cls).filter(
            cls.employee_id == employee_id
        ).order_by(cls.sequence.asc()).all()

        return [group.json for group in groups]
